package com.washing.controller;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.washing.dao.SOrderDao;
import com.washing.dao.SUserAddressDao;
import com.washing.dao.UserDao;
import com.washing.domain.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RestController
public class WashingController {

    private static final Logger logger = LoggerFactory.getLogger(WashingController.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SUserAddressDao sUserAddressDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private SOrderDao sOrderDao;

    @GetMapping("/apiww/index.ashx")
    public Map getMenu(HttpServletRequest request) {
        String host = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();

        List<Map<String, Object>> listjson = new ArrayList<>();

        List<SClass> data = jdbcTemplate.queryForList("select * from s_class", SClass.class);
        for (SClass x : data) {
            List<SGood> mygoods = jdbcTemplate.queryForList("select * from s_goods", SGood.class);

            List<Map<String, Object>> listgood = new ArrayList<>();
            for (SGood gg : mygoods) {
                Map<String, Object> good = new HashMap<>();
                good.put("foodName", gg.getGname());
                good.put("id", gg.getGid());
                good.put("pic", getFirstImg(gg.getGimg()));
                good.put("tag", gg.getgIntroduce());
                good.put("price", gg.getGprice());
                good.put("numb", 0);
                good.put("gdw", gg.getGdw());
                good.put("content", gg.getGcontent().replace("src=\"/upload/", "src=\"" + host + "/upload/"));
                listgood.add(good);
            }

            Map<String, Object> menu = new HashMap<>();
            menu.put("typeName", x.getScname());
            menu.put("GetImgs", getFirstImg(x.getScimg()));
            menu.put("menuContent", listgood);
            listjson.add(menu);
        }

        Map<String, Object> seller = new HashMap<>();
        seller.put("business_end", "21:00");
        seller.put("logourl", host + "/images/logo.png");
        seller.put("name", "小熊工厂洗--演示系统 请勿下单");
        seller.put("min_amount", "99");
        seller.put("business_start", "11:03");
        seller.put("address", "2东路269号");
        seller.put("notice", "洗衣洗鞋新时尚");
        seller.put("telephone", "13378719129");
        seller.put("tel", "0871-66227317");
        seller.put("express_fee", "1");
        seller.put("ad", new String[]{host + "/Up/ad.png", host + "/Up/ad2.png"});

        Map<String, Object> result = new HashMap<>();
        result.put("code", 1);
        result.put("msg", "获取成功");
        result.put("time", System.currentTimeMillis());
        result.put("data", listjson);
        result.put("seller", seller);
        return result;
    }

    private Object getFirstImg(String gimg) {
        return gimg;
    }


    @GetMapping("/apiww/goods/near.ashx")
    public Map<String, Object> getStores(@RequestParam("lon") double lon, @RequestParam("lat") double lat, HttpServletRequest request) {

        List<SStorePress> stores = jdbcTemplate.queryForList("select * from s_store_press", SStorePress.class);

        List<Map<String, Object>> liststore = new ArrayList<>();

        for (SStorePress store : stores) {
            Map<String, Object> storeMap = new HashMap<>();
            storeMap.put("Name", store.getSname());
            storeMap.put("id", store.getSid());
            storeMap.put("pic", getFirstImg(store.getSimg()));
            storeMap.put("slat", store.getSlatitude());
            storeMap.put("slong", store.getSlongitude());
            storeMap.put("iconPath", "/images/park.png");
            storeMap.put("latitude", store.getSlatitude());
            storeMap.put("longitude", store.getSlongitude());
            storeMap.put("width", 32);
            storeMap.put("height", 32);
            storeMap.put("numb", 0);
            storeMap.put("Saddress", store.getSaddress());
            storeMap.put("Stel", store.getStel());
            storeMap.put("Sstime", store.getStime());
            storeMap.put("Setime", store.getEtime());

            double distance = 0.0;
            if (store.getSlatitude() != null && store.getSlongitude() != null) {
                distance = calculateDistance(store.getSlatitude().doubleValue(), store.getSlongitude().doubleValue(), lat, lon);
            }
            storeMap.put("distance", distance);

            liststore.add(storeMap);
        }

        Map<String, Object> response = new HashMap<>();
        response.put("code", 1);
        response.put("msg", "获取成功");
        response.put("time", System.currentTimeMillis());
        response.put("data", liststore);

        return response;
    }

    private double calculateDistance(double latA, double lonA, double latB, double lonB) {
        final int R = 6371; // 地球半径，单位为公里
        double latDistance = Math.toRadians(latB - latA);
        double lonDistance = Math.toRadians(lonB - lonA);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(latA)) * Math.cos(Math.toRadians(latB))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double distance = R * c;
        return distance;
    }


    @GetMapping("/apiww/address/address.ashx")
    public Map<String, Object> getUserAddresses(@RequestHeader(value = "X-ACCESS-USER", required = false) String openid, HttpServletRequest request) {
        if (openid == null || openid.isEmpty()) {
            throw new IllegalArgumentException("parameter error");
        }
        List<SUserAddress> addresses = jdbcTemplate.queryForList("select * from s_user_addresses where openid = " + openid, SUserAddress.class);
        List<Map<String, Object>> addressList = new ArrayList<>();
        for (SUserAddress address : addresses) {
            Map<String, Object> addressMap = new HashMap<>();
            addressMap.put("id", address.getUaid());
            addressMap.put("address_id", address.getUaid());
            addressMap.put("is_default", address.getUastate());
            addressMap.put("name", address.getUpeopleName());
            addressMap.put("phone", address.getUaphone());
            addressMap.put("province_name", address.getUaprovince());
            addressMap.put("city_name", address.getUacity());
            addressMap.put("area_name", address.getUadistrict());
            addressMap.put("addr", address.getUdetailAddress());
            addressMap.put("uaddName", address.getUaddName());

            addressList.add(addressMap);
        }

        Map<String, Object> response = new HashMap<>();
        response.put("code", 1);
        response.put("msg", "收货地址");
        response.put("time", System.currentTimeMillis());
        response.put("data", addressList);
        return response;
    }

    @GetMapping("/apiww/address/edit.ashx")
    public Map<String, Object> editUserAddresses(@RequestHeader(value = "X-ACCESS-USER", required = false) String openid, HttpServletRequest request) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(request.getParameter("paramJson"));
        String name = jsonNode.get("name").asText();
        String iphone = jsonNode.get("iphone").asText();
        String title = jsonNode.get("title").asText();
        String address = jsonNode.get("address").asText();
        String location = jsonNode.get("location").toString();
        String province = jsonNode.get("addname").get("province").asText();
        String city = jsonNode.get("addname").get("city").asText();
        String district = jsonNode.get("addname").get("district").asText();
        String addre = jsonNode.get("addre").asText();
        String isactive = jsonNode.get("isactive").asText();
        String id = jsonNode.get("id").asText();
        int intId = Integer.parseInt(id);
        SUserAddress userAddress;
        if (intId != 0) {
            Optional<SUserAddress> existingAddress = sUserAddressDao.findById((long) intId);
            if (existingAddress.isPresent()) {
                userAddress = existingAddress.get();
            } else {
                userAddress = new SUserAddress();
            }
        } else {
            userAddress = new SUserAddress();
        }

        userAddress.setUopenid(openid);
        userAddress.setUastate(Boolean.parseBoolean(isactive));
        userAddress.setUpeopleName(name);
        userAddress.setUaphone(iphone);
        userAddress.setUaprovince(province);
        userAddress.setUacity(city);
        userAddress.setUadistrict(district);
        userAddress.setUaddress(address);
        userAddress.setUdetailAddress(addre);
        userAddress.setUlatng(location);
        userAddress.setUaddName(title);

        if (intId == 0) {
            sUserAddressDao.save(userAddress);
        } else {
            sUserAddressDao.saveAndFlush(userAddress);
        }

        Map<String, Object> response = new HashMap<>();
        response.put("code", 1);
        response.put("msg", "编辑地址");
        response.put("time", System.currentTimeMillis());
        response.put("id", userAddress.getUaid());
        return response;
    }

    @GetMapping("/apiww/wx/getFullUserInfo.ashx")
    public Map<String, Object> getDetail(HttpServletRequest request) {
        String authToken = request.getHeader("X-ACCESS-USER");

        if (authToken == null || authToken.isEmpty()) {
            throw new IllegalArgumentException("parameter error");
        }

        User user = jdbcTemplate.queryForObject("select * from user where openid = ?", User.class, authToken);

        Map<String, Object> response = new HashMap<>();
        response.put("code", 1);
        response.put("msg", "用户信息");
        response.put("time", LocalDateTime.now());

        if (user != null) {
            // 构造响应数据
            Map<String, Object> data = new HashMap<>();
            data.put("id", user.getUID());
            data.put("token", user.getUGuid());
            HashMap<String, Object> uMap = new HashMap<>();
            uMap.put("image", "https://js.50cms.com/up/jg.png");
            uMap.put("name", getUstat(user.getUstate()));
            data.put("group", uMap);
            data.put("xinji", user.getUstate());
            data.put("levename", getUstat(user.getUstate()));
            data.put("is_store", user.getUstate());
            data.put("isMember", user.isMember());
            data.put("avatar", user.getUHeadImg());
            data.put("username", user.getUNickName());
            data.put("nickname", user.getUNickName());
            data.put("phone_number", user.getUTel());
            data.put("user_type", user.isMember());

            response.put("data", data);
        } else {
            // 创建新用户
            user = new User();
            user.setUGuid(UUID.randomUUID().toString());
            user.setUOpenID(authToken);
            user.setUstate(0);
            user.setUjifen(0);
            user.setRegTime(LocalDateTime.now());
            user.setMember(false);
            userDao.save(user);

            response.put("msg", "注册成功");
            response.put("data", user);
        }

        return response;
    }

    @GetMapping("/wxMiniProgramLogin")
    public Response processRequest(@RequestHeader("X-ACCESS-USER") String openid,
                                   @RequestParam(value = "aid", required = false, defaultValue = "0") int aid,
                                   HttpServletResponse response) throws IOException {
        if (openid == null || openid.isEmpty()) {
            throw new IllegalArgumentException("parameter error");
        }

        String msg = "默认收货地址";
        LocalDateTime time = LocalDateTime.now();

        SUserAddress x = null;

        if (aid == 0) {
            x = sUserAddressDao.findByOpenid(openid);
        } else {
            x = sUserAddressDao.findByOpenidAndAid(openid, aid);
        }

        if (x != null) {
            AddressName addname = new AddressName(
                    x.getUaprovince(),
                    x.getUacity(),
                    x.getUadistrict()
            );

            Area area = new Area(
                    x.getUaddName(),
                    x.getUaddress(),
                    x.getUlatng(),
                    addname
            );

            AddressData data = new AddressData(
                    x.getUaid(),
                    x.getUastate(), // 假设 UAState 为 1 表示默认地址
                    x.getUpeopleName(),
                    x.getUaphone(),
                    x.getUaprovince(),
                    x.getUacity(),
                    x.getUadistrict(),
                    x.getUdetailAddress(),
                    x.getUaddName(),
                    x.getUaddress(),
                    area
            );

            new Response(1, msg, time, data);
        } else {
            return new Response(0, msg, time, null);
        }
        return new Response(1, msg, time, null);
    }


        class AddressName {
            public final String province;
            public final String city;
            public final String district;

            public AddressName(String province, String city, String district) {
                this.province = province;
                this.city = city;
                this.district = district;
            }
        }

        class Area {
            public final String title;
            public final String address;
            public final String location;
            public final AddressName addname;

            public Area(String title, String address, String location, AddressName addname) {
                this.title = title;
                this.address = address;
                this.location = location;
                this.addname = addname;
            }
        }

        class AddressData {
            public final long id;
            public final boolean is_default;
            public final String name;
            public final String phone;
            public final String province_name;
            public final String city_name;
            public final String area_name;
            public final String addr;
            public final String title;
            public final String address;
            public final Area area;

            public AddressData(long id, boolean is_default, String name, String phone, String province_name, String city_name, String area_name, String addr, String title, String address, Area area) {
                this.id = id;
                this.is_default = is_default;
                this.name = name;
                this.phone = phone;
                this.province_name = province_name;
                this.city_name = city_name;
                this.area_name = area_name;
                this.addr = addr;
                this.title = title;
                this.address = address;
                this.area = area;
            }
        }





        private String getUstat(Integer ustate) {
            // 这里应该实现获取状态名称的逻辑
            return "默认状态";
        }


        @GetMapping("/apiww/order/index.ashx")
        public void processRequest(@RequestHeader("X-ACCESS-USER") String openid,
                                   @RequestParam(value = "type", required = false) String type,
                                   @RequestParam(value = "page", required = false, defaultValue = "1") int page,
                                   @RequestParam(value = "numb", required = false, defaultValue = "10") int numb,
                                   HttpServletResponse response) throws IOException {
            if (openid == null || openid.isEmpty()) {
                throw new IllegalArgumentException("parameter error");
            }

            int code = 1;
            String msg = "商品详情";
            LocalDateTime time = LocalDateTime.now();

            List<SOrder> dd = sOrderDao.findByUGUIDAndOParentIdAndOStateGreaterThan(openid, 0, -2, PageRequest.of(page - 1, numb, Sort.by(Sort.Direction.DESC, "orderId")));

            if ("nopay".equals(type)) {
                dd = dd.stream().filter(x -> x.getOState() == -1).collect(Collectors.toList());
            } else if ("nosend".equals(type)) {
                dd = dd.stream().filter(x -> x.getOState() == 0).collect(Collectors.toList());
            } else if ("noget".equals(type)) {
                dd = dd.stream().filter(x -> x.getOState() == 1).collect(Collectors.toList());
            } else if ("nocomment".equals(type)) {
                dd = dd.stream().filter(x -> x.getOState() == 2).collect(Collectors.toList());
            }

            ArrayList<Map<String, Object>> listjson = new ArrayList<>();
            for (SOrder x : dd) {
                List<SOrder> mnews = sOrderDao.findByOParentIdOrOrderId(x.getOParentId(), x.getOrderId());

                ArrayList<Map<String, Object>> lisitem = new ArrayList<>();
                for (SOrder xx : mnews) {
                    Map<String, Object> item = new HashMap<>();
                    item.put("id", xx.getOrderId());
                    item.put("goods_image", xx.getSpImgUrl());
                    item.put("goods_title", xx.getSpName());
                    item.put("goods_price", xx.getSTruePrice());
                    item.put("pay_price", xx.getSTruePrice());
                    item.put("goods_num", xx.getONumber());
                    lisitem.add(item);
                }

                Map<String, Object> order = new HashMap<>();
                order.put("order_sn", x.getOOrderNumber());
                order.put("status", x.getOState());
                order.put("total_fee", x.getOFinalPrice());
                order.put("goods_amount", x.getOFinalPrice());
                order.put("goods_original_amount", x.getOFinalPrice());
                order.put("status_desc", "等待买家付款");
                order.put("pay_fee", x.getOLastPrice());
                order.put("status_name", "待付款");
                order.put("total_amount", getSordeSumMoney(x.getOrderId()));
                order.put("id", x.getOrderId());
                order.put("OrderID", x.getOrderId());
                order.put("item", lisitem);
                order.put("btns", new String[]{"cancel", "pay", "delete"});
                listjson.add(order);
            }

            Map<String, Object> data = new HashMap<>();
            data.put("total", dd.size());
            data.put("per_page", numb);
            data.put("current_page", page);
            data.put("last_page", (int) Math.ceil((double) dd.size() / numb));
            data.put("data", listjson);

            ObjectMapper mapper = new ObjectMapper();
            response.setContentType("application/json");
            response.getWriter().write(mapper.writeValueAsString(new Response(code, msg, time, data)));
        }


        private BigDecimal getSordeSumMoney(Long orderId) {
            // 这里应该实现获取订单总金额的逻辑
            return BigDecimal.ZERO; // 示例返回0
        }

        static class Response {
            public final int code;
            public final String msg;
            public final LocalDateTime time;
            public final Object data;

            public Response(int code, String msg, LocalDateTime time, Object data) {
                this.code = code;
                this.msg = msg;
                this.time = time;
                this.data = data;
            }
        }


    }